/**
******************************************************************************
* @file    vpnstuconfig.c
* @author  Dragon.Chen
* @version V2.0.0
* @date    05-23-2014
* @brief   openvpn和stunnel配置文件
******************************************************************************
* @attention
*
* <h2><center>&copy; COPYRIGHT 2016 上海今中网络科技有限公司 </center></h2>
******************************************************************************
*/

#include "otherconfig.h"

char           *StunnelConfig;
char           *UtunnelConfig;
char           *OpenvpnConfig;
RULE_CONFIG_T   RuleConfig;
///****************patched by xiaohu mod*************2016/03/16*******
CHECK_RUN_INFO_WIN_T             checkRsInfo;
CHECK_PRE_INFO_AND_T             adCheckSInfo;
CHECK_RUN_INFO_AND_T             adCheckRsInfo;
///**********************************************************************
///****************patched by xiaohu mod*************2016/03/17*******
char            check_pre_proc_win_buf[1024];       //processsend.conf
char            check_pre_type_and_buf[1024];       //androidTypesend.conf
char            check_run_proc_win_buf[1024];       //checkrunningsend.conf
///*************************************************************************

/**
  * @brief      去除字符串的首尾空格和回车
  * @param      arg1、待处理字符串
  * @retval     成功返回去除空格的字符串
  */
static char *trim2(char *s)
{
    char *p = s;
    int len = strlen(p);

    while(isspace(p[len - 1]))
		p[--len] = 0;
    while(*p && isspace(*p))
		++p, --len;

    memmove(s, p, len + 1);
    return s;
}

/**
  * @brief      读取stunnel配置文件
  * @param      arg1、文件名
  * @retval     成功返回0，失败-1
  */
static int read_config_of_stunnel(IN PARSE_CONFIG_T *parseConfig, IN const char *fileName)
{
    int      i                     = 0;
    char    *temp                  = NULL;
    char    *savep                 = NULL;
    char     buffer[CONFIG_MAXLEN] = {0};
    FILE    *fp                    = NULL;

    parseConfig->count = 0;
    parseConfig->nameList = NULL;
    parseConfig->valueList = NULL;

    if ((fp = fopen(fileName, "rt")) == NULL)
    	return -1;

    while (fgets(buffer, CONFIG_MAXLEN , fp))
    {
		if (strlen(buffer) < 2)
			continue;

        temp = trim2(buffer);
        if (temp[0] == '#' || temp[0] == '[')
            continue;

        parseConfig->count++;
    }

    parseConfig->nameList  = (char **)calloc(parseConfig->count, sizeof(char *));
    parseConfig->valueList = (char **)calloc(parseConfig->count, sizeof(char *));
    if (freopen(fileName, "rt", fp) == NULL)
        return -1;

    while (fgets(buffer, CONFIG_MAXLEN , fp))
    {
		if (strlen(buffer) < 2)
			continue;

        temp = trim2(buffer);
        if (temp[0] == '#' || temp[0] == '[')
            continue;

        temp = strtok_r(buffer, "=", &savep);
        trim2(temp);
        parseConfig->nameList[i] = strdup(temp);

        temp = strtok_r(NULL, "=", &savep);
        temp = strtok_r(temp, "#", &savep);
        trim2(temp);
        parseConfig->valueList[i++] = strdup(temp);
    }

    parseConfig->getInt         = get_int;
    parseConfig->getString      = get_string;
    parseConfig->setInt         = set_int;
    parseConfig->setString      = set_string;
    parseConfig->commitConfig   = commit_config;
    parseConfig->freeConfig     = free_config;

	fclose(fp);
	return 0;
}

/**
  * @brief      读取openvpn配置文件
  * @param      arg1、文件名
  * @retval     成功返回0，失败-1
  */
static int read_config_of_openvpn(IN PARSE_CONFIG_T *parseConfig, IN const char *fileName)
{
    int      index, length, i      = 0;
    char    *temp                  = NULL;
    char    *savep                 = NULL;
    char     buffer[CONFIG_MAXLEN] = {0};
    FILE    *fp                    = NULL;

    parseConfig->count = 0;
    parseConfig->nameList = NULL;
    parseConfig->valueList = NULL;

    if ((fp = fopen(fileName, "rt")) == NULL)
    	return -1;

    while (fgets(buffer, CONFIG_MAXLEN , fp))
    {
		if (strlen(buffer) < 2)
			continue;

        temp = trim2(buffer);
        if (temp[0] == '#')
            continue;

        parseConfig->count++;
    }

    parseConfig->nameList  = (char **)calloc(parseConfig->count, sizeof(char *));
    parseConfig->valueList = (char **)calloc(parseConfig->count, sizeof(char *));
    if (freopen(fileName, "rt", fp) == NULL)
        return -1;

    while (fgets(buffer, CONFIG_MAXLEN , fp))
    {
		if (strlen(buffer) < 2)
			continue;

        temp = trim2(buffer);
        if (temp[0] == '#')
            continue;

        length = strlen(buffer);
        temp = strtok_r(buffer, " ", &savep);
        index = strlen(temp);
        trim2(temp);
        parseConfig->nameList[i] = strdup(temp);

        if (length == index)
        {
            parseConfig->valueList[i++] = strdup("");
            continue;
        }
        temp = buffer + index + 1;
        temp = strtok_r(temp, "#", &savep);
        trim2(temp);
        parseConfig->valueList[i++] = strdup(temp);
    }

    parseConfig->getInt         = get_int;
    parseConfig->getString      = get_string;
    parseConfig->setInt         = set_int;
    parseConfig->setString      = set_string;
    parseConfig->commitConfig   = commit_config;
    parseConfig->freeConfig     = free_config;

	fclose(fp);
	return 0;
}


/**
  * @brief      获取stunnel信息
  * @param      arg1:stunnel路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_stunnel_config(const char *stunnelPath)
{
    PARSE_CONFIG_T  parseConfig;
    STUNNEL_INFO_T  stunnelInfo;

    parseConfig.readConfig = read_config_of_stunnel;
    assert(parseConfig.readConfig(&parseConfig, stunnelPath) != RETURN_FAILURE);

    stunnelInfo.ciphers     = parseConfig.getString(&parseConfig, "ciphers",  "RC4-MD5");
    stunnelInfo.compression = parseConfig.getString(&parseConfig, "compression", "zlib");
    assert(stunnelInfo.ciphers && stunnelInfo.compression);

    StunnelConfig = (char *)calloc(strlen(stunnelInfo.ciphers) + strlen(stunnelInfo.compression) + 3, 1);
    assert(StunnelConfig != NULL);
    sprintf(StunnelConfig, "%s:%s", stunnelInfo.ciphers, stunnelInfo.compression);

    free(stunnelInfo.ciphers);
    free(stunnelInfo.compression);

    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("StunnelConfig: %s", StunnelConfig);
}

/**
  * @brief      获取utunnel-client头部信息
  * @param      arg1:stunnel路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_utunnel_config(const char *utunnelPath)
{
    int             timeout;
    int             encrypt;
    PARSE_CONFIG_T  parseConfig;

    parseConfig.readConfig = read_config;
    assert_param(parseConfig.readConfig(&parseConfig, utunnelPath) != RETURN_FAILURE);
    timeout = parseConfig.getInt(&parseConfig, "Timeout", 5);
    encrypt = parseConfig.getInt(&parseConfig, "Encrypt", 1);

    UtunnelConfig = (char *)calloc(10, 1);
    assert_param(UtunnelConfig != NULL);
    sprintf(UtunnelConfig, "%d:%d", timeout, encrypt);

    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("UtunnelConfig: %s", UtunnelConfig);
}

/**
  * @brief      获取openvpn信息
  * @param      arg1:openvpn路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_openvpn_config(const char *openvpnPath)
{
    char            buffer[1024] = {0};
    PARSE_CONFIG_T  parseConfig;
    OPENVPN_INFO_T  openvpnInfo;

    parseConfig.readConfig = read_config_of_openvpn;
    assert(parseConfig.readConfig(&parseConfig, openvpnPath) != RETURN_FAILURE);

    openvpnInfo.proto    = parseConfig.getString(&parseConfig, "proto",     "udp");
    openvpnInfo.cipher   = parseConfig.getString(&parseConfig, "cipher",   "null");
    openvpnInfo.auth     = parseConfig.getString(&parseConfig, "auth",     "null");
    openvpnInfo.tun_mtu  = parseConfig.getString(&parseConfig, "tun-mtu",  "null");
    openvpnInfo.fragment = parseConfig.getString(&parseConfig, "fragment", "null");
    openvpnInfo.mssfix   = parseConfig.getString(&parseConfig, "mssfix",   "null");
    openvpnInfo.tls_auth = parseConfig.getString(&parseConfig, "tls-auth", "null");

    assert(openvpnInfo.proto    &&
           openvpnInfo.cipher   &&
           openvpnInfo.auth     &&
           openvpnInfo.tun_mtu  &&
           openvpnInfo.fragment &&
           openvpnInfo.mssfix   &&
           openvpnInfo.tls_auth);

    snprintf(buffer, 1024, "%s:%s:%s:%s:%s:%s:%s",
                openvpnInfo.proto,
                openvpnInfo.cipher,
                openvpnInfo.auth,
                openvpnInfo.tun_mtu,
                openvpnInfo.fragment,
                openvpnInfo.mssfix,
                openvpnInfo.tls_auth);

    OpenvpnConfig = strdup(buffer);
    assert(OpenvpnConfig != NULL);

    free(openvpnInfo.proto);
    free(openvpnInfo.cipher);
    free(openvpnInfo.auth);
    free(openvpnInfo.tun_mtu);
    free(openvpnInfo.fragment);
    free(openvpnInfo.mssfix);
    free(openvpnInfo.tls_auth);

    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("OpenvpnConfig: %s", OpenvpnConfig);
}

///****************patched by yagamishi add*************2016/02/17*******
/**
  * @brief      获取checkrunningswitch信息
  * @param      arg1:checkrunningswitch路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_check_run_win_config(const char *checkRsPath)
{
    PARSE_CONFIG_T  parseConfig;
    parseConfig.readConfig = read_config;
    assert_param(parseConfig.readConfig(&parseConfig, checkRsPath) != RETURN_FAILURE);
    ///****************patched by yagamishi add*************2016/02/20*******
    checkRsInfo.checkSleepTime = parseConfig.getString(&parseConfig, "checkSleepTime","30");
    ///**********************************************************************
    checkRsInfo.twoWay = parseConfig.getString(&parseConfig, "twoWay","0");
    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("checkRsInfo.checkSleepTime: %s", checkRsInfo.checkSleepTime);
    MSG_DEBUG("checkRsInfo.twoWay: %s", checkRsInfo.twoWay);
}
/**
  * @brief      获取adcheckswitch信息
  * @param      arg1:adcheckswitch路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_check_pre_and_config(const char *adCheckSPath)
{
    PARSE_CONFIG_T  parseConfig;
    parseConfig.readConfig = read_config;
    assert_param(parseConfig.readConfig(&parseConfig, adCheckSPath) != RETURN_FAILURE);
    adCheckSInfo.root = parseConfig.getString(&parseConfig, "root","0");
    adCheckSInfo.wifi = parseConfig.getString(&parseConfig, "wifi","0");
    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("adCheckSInfo.root: %s", adCheckSInfo.root);
    MSG_DEBUG("adCheckSInfo.wifi: %s", adCheckSInfo.wifi);
}
/**
  * @brief      获取adcheckrunningswitch信息
  * @param      arg1:adcheckrunningswitch路径
  * @retval     成功返回RETURN_SUCCESS，否则RETURN_FAILURE
  */
void get_check_run_and_config(const char *adCheckRsPath)
{
    PARSE_CONFIG_T  parseConfig;
    parseConfig.readConfig = read_config;
    assert_param(parseConfig.readConfig(&parseConfig, adCheckRsPath) != RETURN_FAILURE);
    ///****************patched by yagamishi add*************2016/02/20*******
    adCheckRsInfo.checkSleepTime = parseConfig.getString(&parseConfig, "checkSleepTime","20");
    ///**********************************************************************
    adCheckRsInfo.twoWay = parseConfig.getString(&parseConfig, "twoWay","0");
    adCheckRsInfo.share = parseConfig.getString(&parseConfig, "share","0");
    adCheckRsInfo.bluetooth = parseConfig.getString(&parseConfig, "bluetooth","0");
    parseConfig.freeConfig(&parseConfig);
    MSG_DEBUG("adCheckRsInfo.checkSleepTime: %s", adCheckRsInfo.checkSleepTime);
    MSG_DEBUG("adCheckRsInfo.twoWay: %s", adCheckRsInfo.twoWay);
    MSG_DEBUG("adCheckRsInfo.share: %s", adCheckRsInfo.share);
    MSG_DEBUG("adCheckRsInfo.bluetooth: %s", adCheckRsInfo.bluetooth);
}
///*************************************************************************


///****************patched by yagamishi add*************2016/02/11*******
///**********把processsend.conf,androidTypesend.conf,checkrunningsend.conf内容写入内存******
/**
  * @brief      获取checks信息
  * @param      arg1:checks路径 arg2: out buf
  * @retval     void
  */
void get_check_configs(const char *filename,char *buf){
    char *buffer;

    memset(buf,0,1024);
    FILE *fp;
    assert_param( (fp = fopen(filename,"r")) != NULL );
    buffer = calloc(128, sizeof(char*));
    while(fgets(buffer,128,fp)!=NULL)
    {
   			 strcat(buf,buffer);
   			 memset(buffer,0,128);
    }
    free(buffer);
    if(fp != NULL)
    {
        fclose(fp);
    }
}
//*************************************************************************

/**
  * @brief  读取配置文件信息
  * @param  arg1:rule path
  * @retval 成功返回0，否则-1
  */
void get_rule_config(const char *rulePath)
{
    PARSE_CONFIG_T  parseConfig;

    parseConfig.readConfig = read_config;
	assert(parseConfig.readConfig(&parseConfig, rulePath) != RETURN_FAILURE);

	RuleConfig.serialNumber     = parseConfig.getInt(&parseConfig, "SerialNumber",     0);
	RuleConfig.commomName       = parseConfig.getInt(&parseConfig, "CommomName",       1);
	RuleConfig.hardwarePlatform = parseConfig.getInt(&parseConfig, "HardwarePlatform", 0);
	RuleConfig.hardwareSN       = parseConfig.getInt(&parseConfig, "HardwareSN",       1);
	RuleConfig.OSVersion        = parseConfig.getInt(&parseConfig, "OSVersion",        0);
	RuleConfig.phoneNumber      = parseConfig.getInt(&parseConfig, "PhoneNumber",      0);
	RuleConfig.clientVersion    = parseConfig.getInt(&parseConfig, "ClientVersion",    0);
	RuleConfig.nLogin           = parseConfig.getInt(&parseConfig, "TestCount",        3);
	RuleConfig.verify           = parseConfig.getInt(&parseConfig, "DoVerify",         1);

    MSG_DEBUG("rule config information as below:" CR
              "SerialNumber               = %d"   CR
              "CommomName                 = %d"   CR
              "HardwarePlatform           = %d"   CR
              "HardwareSN                 = %d"   CR
              "OSVersion                  = %d"   CR
              "PhoneNumber                = %d"   CR
              "ClientVersion              = %d"   CR
              "NLogin                     = %d"   CR
              "Verify                     = %d"   CR
              "rule config information end!",

              RuleConfig.serialNumber,
              RuleConfig.commomName,
              RuleConfig.hardwarePlatform,
              RuleConfig.hardwareSN,
              RuleConfig.OSVersion,
              RuleConfig.phoneNumber,
              RuleConfig.clientVersion,
              RuleConfig.nLogin,
              RuleConfig.verify);

	parseConfig.freeConfig(&parseConfig);
}

/******************* (C) COPYRIGHT 2014 上海今中网络科技有限公司 *****END OF FILE****/














